﻿using Sustainalytics.ClientDW.Synchronization.SyncESGData.AbstractClassesAndInterfaces;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.CorporateDataLogic;
using System.Linq;
using System.Threading.Tasks;
using Sustainalytics.SharedEntities.EsgResearch;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.EsgResearchProfileLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.ESGAssessmentThresholdLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.IndicatorTemplateLogic;
using System.Collections.Generic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPCompanyESGComputationResultLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPCompanyProfileLogic;
using Sustainalytics.ClientDW.Synchronization.SyncESGData.RPIndicatorExtendedLogic;

namespace Sustainalytics.ClientDW.Synchronization.SyncESGData
{
    public class CoreEsgSync
    {
        private readonly ICoreEsgCompaniesIdsQuery coreEsgCompaniesIdsQuery;
        private readonly ICoreEsgResearchProfileQuery coreEsgResearchProfileQuery;
        private readonly ICorporateDataCoreEsgProcessor corporateDataCoreEsgProcessor;
        private readonly IComprehensiveEsgSyncOrchestrator<EsgAssessmentThreshold> esgAssessmentThresholdOrchestrator;// there is only 1 catalog for both core and comprehensive ESG overall assessment
        private readonly ICoreEsgSyncOrchestrator<EsgResearchProfile> coreEsgResearchProfileOrchestrator;
        private readonly IComprehensiveEsgSyncOrchestrator<IndicatorTemplate> indicatorTemplateOrchestrator;// managed by the comprehensive ESG research but used by the core ESG research as well
        private readonly List<IndicatorTemplate> indicatorTemplates;
        private readonly ICoreEsgSyncOrchestrator<EsgResearchProfile> coreRPCompanyESGComputationResultOrchestrator;
        private readonly ICoreEsgSyncOrchestrator<EsgResearchProfile> coreRPCompanyProfileOrchestrator;
        private readonly ICoreEsgSyncOrchestrator<EsgResearchProfile> coreRPIndicatorExtendedOrchestrator;                

        public CoreEsgSync(
            EsgCompaniesIdsQuery coreEsgCompaniesIdsQuery,
            EsgResearchProfileQuery coreEsgResearchProfileQuery,
            CorporateDataProcessor corporateDataCoreEsgProcessor,
            EsgAssessmentThresholdOrchestrator esgAssessmentThresholdOrchestrator,
            EsgResearchProfileOrchestrator coreEsgResearchProfileOrchestrator,
            IndicatorTemplateOrchestrator indicatorTemplateOrchestrator,
            List<IndicatorTemplate> indicatorTemplates,
            RPCompanyESGComputationResultOrchestrator coreRPCompanyESGComputationResultOrchestrator,
            RPCompanyProfileOrchestrator coreRPCompanyProfileOrchestrator,
            RPIndicatorExtendedOrchestrator coreRPIndicatorExtendedOrchestrator)
        {
            this.coreEsgCompaniesIdsQuery = coreEsgCompaniesIdsQuery;
            this.coreEsgResearchProfileQuery = coreEsgResearchProfileQuery;
            this.corporateDataCoreEsgProcessor = corporateDataCoreEsgProcessor;
            this.esgAssessmentThresholdOrchestrator = esgAssessmentThresholdOrchestrator;
            this.coreEsgResearchProfileOrchestrator = coreEsgResearchProfileOrchestrator;
            this.indicatorTemplateOrchestrator = indicatorTemplateOrchestrator;
            this.indicatorTemplates = indicatorTemplates;
            this.coreRPCompanyESGComputationResultOrchestrator = coreRPCompanyESGComputationResultOrchestrator;
            this.coreRPCompanyProfileOrchestrator = coreRPCompanyProfileOrchestrator;
            this.coreRPIndicatorExtendedOrchestrator = coreRPIndicatorExtendedOrchestrator;            
        }

        public async Task<int> StartAsync(bool syncEntitiesSharedWithComprehensiveEsgResearch = false)
        {
            var coreEsgCompaniesIds = await coreEsgCompaniesIdsQuery.GetAsync().ConfigureAwait(false);
            var coreEsgResearchProfiles = coreEsgResearchProfileQuery.Get(coreEsgCompaniesIds.CompaniesWithActiveResearch);

            if (coreEsgResearchProfiles.Count == 0) return 0;

            var sharedOrchestrators = syncEntitiesSharedWithComprehensiveEsgResearch ? new []
                {
                    esgAssessmentThresholdOrchestrator.OrchestrateAsync(),
                    indicatorTemplateOrchestrator.OrchestrateAsync(indicatorTemplates)
                } : new Task[0];

            await Task.WhenAll(sharedOrchestrators.Concat(new[]
            {
                coreEsgResearchProfileOrchestrator.OrchestrateAsync(coreEsgResearchProfiles, coreEsgCompaniesIds.InvalidatedCompanies),
                coreRPCompanyESGComputationResultOrchestrator.OrchestrateAsync(coreEsgResearchProfiles, coreEsgCompaniesIds.InvalidatedCompanies),
                coreRPCompanyProfileOrchestrator.OrchestrateAsync(coreEsgResearchProfiles, coreEsgCompaniesIds.InvalidatedCompanies),
                coreRPIndicatorExtendedOrchestrator.OrchestrateAsync(coreEsgResearchProfiles, coreEsgCompaniesIds.InvalidatedCompanies)
            })).ConfigureAwait(false);

            await corporateDataCoreEsgProcessor.SetResearchInProgress(coreEsgCompaniesIds.CompaniesWithActiveResearch.Where(cId => coreEsgResearchProfiles.All(rp => rp.Id != cId)));

            return coreEsgResearchProfiles.Count;
        }
    }
}
